package com.alex.distributedlockredis.simplelock;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisLockAlex008 {
    private final StringRedisTemplate redisTemplate;

    public RedisLockAlex008(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 尝试获取分布式锁
     * @param lockKey    锁的key
     * @param requestId  请求标识（用于释放锁时确认是否为自己的锁）
     * @param expireTime 锁的过期时间
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long expireTime) {
        // setIfAbsent等同于Redis的SETNX命令
        // 只有在key不存在时才能设置成功，这就实现了锁的互斥性
        ValueOperations<String, String> valueOps =
                redisTemplate.opsForValue();  //  1. 获取操作字符串（value）的接口
        Boolean succes = valueOps.setIfAbsent(lockKey, requestId, expireTime, TimeUnit.SECONDS);

        if (Boolean.TRUE.equals(succes)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 释放分布式锁
     * @param lockKey 锁的key
     * @param requestId 请求标识
     * @return 是否释放成功
     */
    public boolean releaseLock(String lockKey, String requestId) {
        // 获取锁中的值，与requestId比较，如果相同则删除锁
        String currentValue = redisTemplate.opsForValue().get(lockKey);
        if (requestId.equals(currentValue)) {
            return Boolean.TRUE.equals(redisTemplate.delete(lockKey));
        }
        return false;
    }
}
